package com.ruoyi.finance.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.ruoyi.IndexDtoByTwo;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.finance.domain.*;
import com.ruoyi.finance.mapper.BuyPayReqMapper;
import com.ruoyi.finance.mapper.BuyPayReqRefCgrkMapper;
import com.ruoyi.finance.mapper.PaymentDetailMapper;

import com.ruoyi.finance.service.IBuyMustPayService;
import com.ruoyi.store.api.RemoteStockInXService;
import com.ruoyi.system.api.dto.StockInDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.finance.mapper.PaymentMapper;
import com.ruoyi.finance.service.IPaymentService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * 付款单Service业务层处理
 *
 * @author lvql
 * @date 2024-11-08
 */
@Service
public class PaymentServiceImpl implements IPaymentService {
    @Autowired
    private PaymentMapper paymentMapper;

    @Autowired
    private PaymentDetailMapper paymentDetailMapper;

    @Autowired
    private BuyPayReqMapper buyPayReqMapper;

    @Autowired
    private BuyPayReqRefCgrkMapper buyPayReqRefCgrkMapper;

    @Autowired
    private RemoteStockInXService remoteStockInXService;

    @Autowired
    private IBuyMustPayService buyMustPayService;

    /**
     * 查询付款单
     *
     * @param id 付款单主键
     * @return 付款单
     */
    @Override
    public Payment selectPaymentById(Integer id) {
        Payment payment = paymentMapper.selectPaymentById(id);
        String code = payment.getCode();
        PaymentDetail paymentDetail = new PaymentDetail();
        paymentDetail.setPaymentCode(code);
        List<PaymentDetail> paymentDetails = paymentDetailMapper.selectPaymentDetailList(paymentDetail);
        payment.setList(paymentDetails);
        return payment;
    }

    @Override
    public IndexDtoByTwo getBuyPayCountAndMoney() {
        return paymentMapper.getBuyPayCountAndMoney();
    }

    /**
     * 查询付款单列表
     *
     * @param payment 付款单
     * @return 付款单
     */
    @Override
    public List<Payment> selectPaymentList(Payment payment) {
        return paymentMapper.selectPaymentList(payment);
    }

    @Override
    public List<Payment> getReconList(Payment payment) {
        return paymentMapper.getReconList(payment);
    }

    @Override
    public IndexDtoByTwo getSaleBuckPayCountAndMoney() {
        return paymentMapper.getSaleBuckPayCountAndMoney();
    }

    /**
     * 新增付款单
     *
     * @param payment 付款单
     * @return 结果
     */
    @Transactional
    @Override
    public int insertPayment(Payment payment) {
        payment.setCreateTime(DateUtils.getNowDate());
        List<PaymentDetail> list = payment.getList();
        BigDecimal bigDecimal = new BigDecimal(0);
        if (list != null && list.size() > 0) {
            for (PaymentDetail paymentDetail : list) {
                paymentDetail.setPaymentCode(payment.getCode());
                bigDecimal = bigDecimal.add(paymentDetail.getTotalAmount());
                paymentDetailMapper.insertPaymentDetail(paymentDetail);
            }
        }
        payment.setTotalAmount(bigDecimal);
        payment.setVerifiedAmount(BigDecimal.ZERO);
        payment.setDocMakeUserId(Math.toIntExact(SecurityUtils.getUserId()));
        return paymentMapper.insertPayment(payment);
    }

    /**
     * 修改付款单
     *
     * @param payment 付款单
     * @return 结果
     */
    @Transactional
    @Override
    public int updatePayment(Payment payment) {
        payment.setUpdateTime(DateUtils.getNowDate());
        List<PaymentDetail> list = payment.getList();
        BigDecimal bigDecimal = new BigDecimal(0);
        for (PaymentDetail paymentDetail : list) {
            bigDecimal = bigDecimal.add(paymentDetail.getTotalAmount());
            paymentDetailMapper.updatePaymentDetail(paymentDetail);
        }
        payment.setTotalAmount(bigDecimal);
        return paymentMapper.updatePayment(payment);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int approvalPayment(Payment payment) {
        payment.setApprovalUserId(Math.toIntExact(SecurityUtils.getUserId()));
        //一个付款单  有多个付款申请单
        //一次循环就是 对一个付款申请 处理
        //一个付款申请 有多个入库单
        for (PaymentDetail paymentDetail : payment.getList()) {
            //1.对一个付款申请单处理
            BigDecimal totalAmount = paymentDetail.getTotalAmount(); // 付款单的金额  可以小于申请单的申请金额
            String sourceCode = paymentDetail.getSourceCode();//付款申请号

            //2.通过付款申请单号 查询付款申请单
            BuyPayReq buyPayReqQuery = new BuyPayReq();
            buyPayReqQuery.setCode(sourceCode);
            List<BuyPayReq> buyPayReqList= buyPayReqMapper.selectBuyPayReqList(buyPayReqQuery);
            Assert.notEmpty(buyPayReqList,"付款申请为空");
            BuyPayReq fksq = buyPayReqList.get(0);//付款申请单
            BigDecimal requestTotalAmount = fksq.getRequestAmount();//付款申请单的申请金额
            //3.通过付款申请单号 查询采购付款申请详情列表
            BuyPayReqRefCgrk buyPayReqRefCgrk = new BuyPayReqRefCgrk();
            buyPayReqRefCgrk.setPayReqCode(sourceCode);
            List<BuyPayReqRefCgrk> buyPayReqRefCgrks = buyPayReqRefCgrkMapper.selectBuyPayReqRefCgrkList(buyPayReqRefCgrk);


            BigDecimal totalWaitPaidAmount =  new BigDecimal(0);
            for (BuyPayReqRefCgrk payReqRefCgrk : buyPayReqRefCgrks) {
                //（未）支付金额  =  申请金额 - 已支付金额
                totalWaitPaidAmount = totalWaitPaidAmount.add(
                        payReqRefCgrk.getRequestAmount().subtract(payReqRefCgrk.getPaidAmount())
                );
            }
            //4.判断支付金额是否 大于未核销金额
            if (totalAmount.compareTo(totalWaitPaidAmount)>0){
                throw new ServiceException("支付金额不能大于未支付金额");
            }

            //5.处理申请单中的每一个入库单
            //一次循环就是对一个 入库单 和 应付单 处理
            for (BuyPayReqRefCgrk payReqRefCgrk : buyPayReqRefCgrks) {

                //待（未）核销金额  =  申请金额 - 已核销金额
                BigDecimal waitPaidAmount = payReqRefCgrk.getRequestAmount().subtract(payReqRefCgrk.getPaidAmount());
                BigDecimal requestAmount = payReqRefCgrk.getRequestAmount();//付款申请单详情 关联入库单 申请金额
                // 申请金额占比
//                BigDecimal percentage = requestAmount.divide(requestTotalAmount, 2, BigDecimal.ROUND_HALF_UP);
//                BigDecimal waitPaidAmount = totalAmount.multiply(percentage);//等待核销的金额

                String rkCode = payReqRefCgrk.getSourceCode(); //入库单据编号
                //通过入库单号 查询应付单
                BuyMustPay buyMustPayQuery = new BuyMustPay();
                buyMustPayQuery.setSourceCode(rkCode);
                List<BuyMustPay> buyMustPays = buyMustPayService.selectBuyMustPayList(buyMustPayQuery);
                Assert.notEmpty(buyMustPays, "应付单不存在");

                BuyMustPay buyMustPay = buyMustPays.get(0);
                BigDecimal buyMustPayTotalAmount = buyMustPay.getTotalAmount(); //应付单总金额
                BigDecimal verifiedAmount = buyMustPay.getVerifiedAmount();//应付单已核销的金额
                if (waitPaidAmount.compareTo(buyMustPayTotalAmount.subtract(verifiedAmount)) > 0) {
                    throw new ServiceException("核销金额不能大于未核销金额");
                }
                //如果支付金额大于 一个申请单关联入库单 未核销的金额
                if(totalAmount.compareTo(waitPaidAmount)>=0){
                    if (buyMustPayService.verified(buyMustPay, waitPaidAmount) == 0) {
                        throw new ServiceException("核销失败");
                    }
                    //核销成功  更新付款申请详情单
                    payReqRefCgrk.setPaidAmount(payReqRefCgrk.getPaidAmount().add(waitPaidAmount));
                    buyPayReqRefCgrkMapper.updateBuyPayReqRefCgrk(payReqRefCgrk);
                    totalAmount = totalAmount.subtract(waitPaidAmount);
                }else if (totalAmount.compareTo(waitPaidAmount)<0){
                    if (buyMustPayService.verified(buyMustPay, totalAmount) == 0) {
                        throw new ServiceException("核销失败");
                    }

                    //核销成功  更新付款申请详情单
                    payReqRefCgrk.setPaidAmount(payReqRefCgrk.getPaidAmount().add(totalAmount));
                    buyPayReqRefCgrkMapper.updateBuyPayReqRefCgrk(payReqRefCgrk);
                    totalAmount = BigDecimal.ZERO;
                }
            }
            //付款申请详情成功更新  更新付款申请单

            //如果（申请金额减去已付金额）等于  付款金额  改变  付款申请状态 关闭申请单
            if ( (fksq.getRequestAmount().subtract(fksq.getPaidAmount()))
                    .compareTo(paymentDetail.getTotalAmount()) == 0){
                fksq.setIsClose(1);
                fksq.setDocStage(2);
            }
            fksq.setPaidAmount(fksq.getPaidAmount().add(paymentDetail.getTotalAmount()));
            if (buyPayReqMapper.updateBuyPayReqByCode(fksq)==0) {
                throw new ServiceException("付款申请更新失败");
            }
        }
//        10，11，16，26，24，、
        payment.setVerifiedAmount(payment.getTotalAmount());
        return paymentMapper.updatePayment(payment);
    }

    /**
     * 批量删除付款单
     *
     * @param ids 需要删除的付款单主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deletePaymentByIds(Integer[] ids) {
        List<Payment> payments = paymentMapper.selectPaymentByIds(ids);
        List<String> codeList = new ArrayList<>();
        for (Payment payment : payments) {
            codeList.add(payment.getCode());
        }
        if (!codeList.isEmpty()) {
            paymentDetailMapper.deletePaymentDetailByPaymentCode(codeList);
        }
        return paymentMapper.deletePaymentByIds(ids);
    }

    /**
     * 删除付款单信息
     *
     * @param id 付款单主键
     * @return 结果
     */
    @Override
    public int deletePaymentById(Integer id) {
        return paymentMapper.deletePaymentById(id);
    }


}
